import pickle
from typing import Annotated

from fastapi import APIRouter, Header, Depends

from app_v2.bili_api.api import ApiSession
from app_v2.bili_api.model import VideoInfo
from app_v2.dependencys import get_redis

me = APIRouter(prefix="/me", tags=["me"])


@me.get("/info")
async def my_info(token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("me:info:{}".format(token))
        if data:
            return {
                "code": 200,
                "data": pickle.loads(data),
            }

    async with ApiSession(token) as session:
        me = await session.me()
        info = await me.info()

    await redis.setex("me:info:{}".format(token), 3600 * 1, pickle.dumps(info))
    return {
        "code": 200,
        "data": info,
    }


@me.get("/video_coin")
async def my_video_coin(token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("me:video_coin:{}".format(token))
        if data:
            return {
                "code": 200,
                "data": pickle.loads(data),
            }

    async with ApiSession(token) as session:
        me = await session.me()
        infos = await me.recent_video_coin()
    res = [VideoInfo(info, []).to_dict() for info in infos["data"]]
    await redis.setex("me:video_coin:{}".format(token), 3600 * 1, pickle.dumps(res))
    return {
        "code": 200,
        "data": res,
    }


@me.get("/video_like")
async def my_video_like(token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("me:video_like:{}".format(token))
        if data:
            return {
                "code": 200,
                "data": pickle.loads(data),
            }

    async with ApiSession(token) as session:
        me = await session.me()
        infos = await me.recent_video_like()

    res = [VideoInfo(info, []).to_dict() for info in infos["data"]["list"]]
    await redis.setex("me:video_like:{}".format(token), 3600 * 1, pickle.dumps(res))
    return {
        "code": 200,
        "data": res,
    }


@me.get("/word_cloud")
async def my_word_cloud(token: Annotated[str | None, Header()], n: int = 20,
                        redis=Depends(get_redis)):
    val = await redis.get("me:word_cloud:{}".format(token))
    if val:
        return {
            "code": 200,
            "data": pickle.loads(val)
        }

    async with ApiSession(token) as session:
        me = await session.me()
        data = await me.user_word_cloud()
    data = [{"text": word, "size": count} for word, count in data[:n]]
    await redis.get_client("me_word_cloud_cache").setex("me:word_cloud:{}".format(token), 3600 * 24, pickle.dumps(data))
    return {
        "code": 200,
        "data": data
    }
